package com.ruoyi.system.service.impl;

import java.io.IOException;
import java.util.*;

import com.ruoyi.system.domain.TbUpeModel;
import com.ruoyi.system.domain.upe.*;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.TbUpeModelverMapper;
import com.ruoyi.system.domain.TbUpeModelver;
import com.ruoyi.system.service.ITbUpeModelverService;
import org.springframework.web.multipart.MultipartFile;


/**
 * 流程模型版本Service业务层处理
 * 
 * @author gxt
 * @date 2024-08-23
 */
@Service
public class TbUpeModelverServiceImpl implements ITbUpeModelverService 
{
    @Autowired
    private TbUpeModelverMapper tbUpeModelverMapper;

    private  TbUpeModel model = new TbUpeModel();

    /**
     * 查询流程模型版本
     * 
     * @param wfid 流程模型版本主键
     * @return 流程模型版本
     */
    @Override
    public TbUpeModelver selectTbUpeModelverByWfid(String wfid)
    {
        return tbUpeModelverMapper.selectTbUpeModelverByWfid(wfid);
    }

    /**
     * 查询流程模型版本列表
     * 
     * @param tbUpeModelver 流程模型版本
     * @return 流程模型版本
     */
    @Override
    public List<TbUpeModelver> selectTbUpeModelverList(TbUpeModelver tbUpeModelver)
    {
        return tbUpeModelverMapper.selectTbUpeModelverList(tbUpeModelver);
    }

    /**
     * 新增流程模型版本
     * 
     * @param tbUpeModelver 流程模型版本
     * @return 结果
     */
    @Override
    public int insertTbUpeModelver(TbUpeModelver tbUpeModelver)
    {
        return tbUpeModelverMapper.insertTbUpeModelver(tbUpeModelver);
    }

    /**
     * 修改流程模型版本
     * 
     * @param tbUpeModelver 流程模型版本
     * @return 结果
     */
    @Override
    public int updateTbUpeModelver(TbUpeModelver tbUpeModelver)
    {
        return tbUpeModelverMapper.updateTbUpeModelver(tbUpeModelver);
    }

    /**
     * 批量删除流程模型版本
     * 
     * @param wfids 需要删除的流程模型版本主键
     * @return 结果
     */
    @Override
    public int deleteTbUpeModelverByWfids(String[] wfids)
    {
        return tbUpeModelverMapper.deleteTbUpeModelverByWfids(wfids);
    }

    /**
     * 删除流程模型版本信息
     * 
     * @param wfid 流程模型版本主键
     * @return 结果
     */
    @Override
    public int deleteTbUpeModelverByWfid(String wfid)
    {
        return tbUpeModelverMapper.deleteTbUpeModelverByWfid(wfid);
    }

    @Override
    public TbUpeModel parseXml(MultipartFile file) throws IOException, JDOMException {
        // 解析xml
        Document doc = null;
        SAXBuilder sb = new SAXBuilder();
        doc = sb.build(file.getInputStream());
        Element root = doc.getRootElement();
        List<Element> elements_1 = root.getChildren();
        for(Element e1 : elements_1) {
            String e1name=e1.getName();
            if(e1name.equals("name")) {
                // 流程名称
                model.setWfname(e1.getValue());
            }else if(e1name.equals("description")) {
                // 流程模板描述
                model.setWfdesc(e1.getValue());
            }else if(e1name.equals("image_file")) {
                model.setImage_file(e1.getValue());
            }else if(e1name.equals("version")) {
                // 版本号
                model.setVersion(e1.getValue());
            }else if(e1name.equals("base_show")) {
                // 显示模板文件名
                model.setBase_show(e1.getChild("name").getValue());
            }else if(e1name.equals("base_submit")) {
                // 提交模板文件名
                model.setBase_submit(e1.getChild("name").getValue());
            }else if(e1name.equals("source_attributes")) {
                model.setSource_attributes(parse_source_attributes(e1));
            }else if(e1name.equals("opt_attributes")) {
                model.setOpt_attributes(parse_opt_attributes(e1));
            }else if(e1name.equals("states")) {
                model.setStates(parse_states(e1));
            }else if(e1name.equals("transitions")) {
                model.setTransitions(parse_transitions(e1));
            }
        }
        return model;
    }

    public Hashtable<String, SAttribute> parse_source_attributes(Element e) {
        Hashtable<String, SAttribute> source_attributes=new Hashtable<String, SAttribute>();

        // 流程模板使用的属性定义
        List<Element> elements_1 = e.getChildren();
        for(Element e1 : elements_1) {
            List<Element> elements_2 = e1.getChildren();

            // 属性英文名称
            String attr_name=null;
            // DB类型
            String attr_type=null;
            // WEB类型
            String web_type=null;
            // 属性中文名称
            String alias=null;
            // 属性描述
            String description=null;
            // 静态数据定义
            ListBox listbox_values=null;
            for(Element e2 : elements_2) {
                String e2name=e2.getName();

                if(e2name.equals("name")) {
                    attr_name=e2.getValue();
                }else if(e2name.equals("type")) {
                    attr_type=e2.getValue();
                }else if(e2name.equals("web_type")) {
                    web_type=e2.getValue();
                }else if(e2name.equals("alias")) {
                    alias=e2.getValue();
                }else if(e2name.equals("description")) {
                    description=e2.getValue();
                }else if(e2name.equals("listbox_script")) {
                    // 检查是否存在下级节点
                    if(e2.getChildren().size() > 0) {
                        String defaultkey=e2.getAttribute("default").getValue();
                        List<Element> options=e2.getChildren();

                        String type=null;
                        String script=null;
                        Hashtable<String, String> h=new Hashtable<String, String>();
                        for(Element option : options) {
                            String option_name=option.getName();
                            if(option_name.equals("type"))
                                type=option.getValue();
                            else if(option_name.equals("script"))
                                script=option.getValue();
                        }

                        listbox_values=parse_listbox(type, script, defaultkey);
                    }
                }
            }

            SAttribute sattribute=new SAttribute(attr_name, attr_type, web_type, alias, description, listbox_values);
            source_attributes.put(attr_name, sattribute);
        }

        return source_attributes;
    }

    public ListBox parse_listbox(String type, String script, String defaultkey) {
        // dict:数据字典, 在script节点定义key和value,格式为：key,value;key,value;key,value
        // sql:SQL脚本，必须以 SELECT 字段1,字段2 开头，支持脚本中嵌入变量，变量值集合由调用者传入
        // java:指定Java类，该类必须实现com.finedo.upe.ListBoxInterface接口

        if(type == null || script == null)
            return null;

        // key,value
        Hashtable<String, String> options=new Hashtable<String, String>();

        if(type.equals("dcit")) {
            String line[]=script.split(";");
            for(String data : line) {
                String arr[]=data.split(",");
                String key=arr[0];
                String value=arr[1];

                options.put(key, value);
            }
        }else if(type.equals("sql")) {

        }else if(type.equals("java")) {

        }else {
            return null;
        }

        return new ListBox(defaultkey, options);
    }

    public Hashtable<String, OAttribute> parse_opt_attributes(Element e) {
        Hashtable<String, OAttribute> opt_attributes=new Hashtable<String, OAttribute>();

        // 默认显示对话框定义
        List<Element> elements_1 = e.getChildren();

        for(Element e1 : elements_1) {
            List<Element> elements_2 = e1.getChildren();

            // 属性英文名称
            String attr_name=null;
            // 属性中文名称
            String alias=null;
            // WEB类型
            String web_type=null;
            // 高度：像素
            int height=0;
            // 宽度：像素
            int length=0;
            // 排序序号
            int sort_order=0;
            // 跨度列
            int span_column=0;
            // 默认值
            String default_value=null;
            // 初始状态
            boolean expanded=false;
            // true:可修改  false：只读
            boolean writable=true;
            // true:非必填 false: 必填
            boolean isnull=true;
            for(Element e2 : elements_2) {
                String e2name=e2.getName();

                if(e2name.equals("name")) {
                    attr_name=e2.getValue();
                }else if(e2name.equals("alias")) {
                    alias=e2.getValue();
                }else if(e2name.equals("web_type")) {
                    web_type=e2.getValue();
                }else if(e2name.equals("height")) {
                    try {
                        height=Integer.parseInt(e2.getValue());
                    }catch(Exception ee) {
                        height=0;
                    }
                }else if(e2name.equals("length")) {
                    try {
                        length=Integer.parseInt(e2.getValue());
                    }catch(Exception ee) {
                        length=0;
                    }
                }else if(e2name.equals("sort_order")) {
                    try {
                        sort_order=Integer.parseInt(e2.getValue());
                    }catch(Exception ee) {
                        sort_order=0;
                    }
                }else if(e2name.equals("span_column")) {
                    try {
                        span_column=Integer.parseInt(e2.getValue());
                    }catch(Exception ee) {
                        span_column=0;
                    }
                }else if(e2name.equals("default_value")) {
                    default_value=e2.getValue();
                }else if(e2name.equals("expanded")) {
                    expanded=e2.getValue().equals("true");
                }else if(e2name.equals("writable")) {
                    writable=e2.getValue().equals("true");
                }else if(e2name.equals("isnull")) {
                    isnull=e2.getValue().equals("true");
                }
            }

            ListBox listbox_values=null;
            // 检查是否为web_listbox属性
            if(web_type.equals("web_listbox")) {
                listbox_values=((SAttribute)(model.source_attributes.get(attr_name))).listbox_values;
            }

            OAttribute oattribute=new OAttribute(attr_name, alias, web_type, height, length, sort_order, span_column, default_value, expanded, writable, isnull, listbox_values);
            opt_attributes.put(attr_name, oattribute);
        }

        return opt_attributes;
    }

    public Hashtable<String, State> parse_states(Element e) {
        Hashtable<String, State> states= new Hashtable<String, State>();

        List<Element> elements_1 = e.getChildren();
        for(Element e1 : elements_1) {
            List<Element> elements_2 = e1.getChildren();

            // 状态英文名
            String name=null;
            // 状态中文名
            String alias=null;
            // 状态描述
            String description=null;
            // 状态类型
            String type=null;
            // 状态显示对话框定义
            Hashtable<String, OAttribute> opt_attributes=null;
            // 时效，单位：分钟
            int timecost=0;
            for(Element e2 : elements_2) {
                String e2name=e2.getName();

                if(e2name.equals("name")) {
                    name=e2.getValue();
                }else if(e2name.equals("alias")) {
                    alias=e2.getValue();
                }else if(e2name.equals("description")) {
                    description=e2.getValue();
                }else if(e2name.equals("type")) {
                    type=e2.getValue();
                }else if(e2name.equals("opt_attributes")) {
                    opt_attributes=parse_opt_attributes(e2);
                }else if(e2name.equals("timecost")) {
                    try {
                        timecost=Integer.parseInt(e2.getValue());
                    }catch(Exception ee) {
                        timecost=0;
                    }
                }
            }
            State state=new State(name, alias, description, type, opt_attributes, timecost);
            states.put(name, state);
        }

        return states;
    }


    public UserScript parse_user_script(Element e) {
        // 处理人集合名称、描述
        String name=null;
        // 处理人控件类型
        String uiface=null;

        List<Element> elements_1 = e.getChildren();
        for(Element e1 : elements_1) {

            String e1name=e1.getName();

            if(e1name.equals("name")) {
                name=e1.getValue();
            }else if(e1name.equals("uiface")) {
                uiface=e1.getValue();
            }

        }


        UserScript userscript=new UserScript(name, uiface);

        // basic_select：普通下拉框
        if(uiface.equals(Constants.UIFACE_BASIC_SELECT)) {
            List<Element> nodelist=e.getChildren(Constants.UIFACE_BASIC_SELECT + "_script");
            if(nodelist.size() == 1) {
                // 正确

                String type=null;
                String script=null;
                String defaultvalue=null;

                List<Element> elements_2 =nodelist.get(0).getChildren();
                for(Element e2 : elements_2) {
                    String e2name=e2.getName();

                    if(e2name.equals("type")) {
                        type=e2.getValue();
                    }else if(e2name.equals("script")) {
                        script=e2.getValue();
                    }else if(e2name.equals("defaultvalue")) {
                        defaultvalue=e2.getValue();
                    }
                }

                userscript.basic_select_script=new BasicSelectScript(type, script, defaultvalue);
                //判断type是否正确
                if(type.equals("user") || type.equals("role") || type.equals("sql") || type.equals("transition") || type.equals("java")) {
                    // 正确
                }else {

                }
            }else {

            }
        }

        // link_select: 联动下拉框
        if(uiface.equals(Constants.UIFACE_LINK_SELECT)) {
            List<Element> nodelist=e.getChildren(Constants.UIFACE_LINK_SELECT + "_script");
            if(nodelist.size() == 1) {
                // 正确

                String a_script=null;
                String b_script=null;

                List<Element> elements_2 =nodelist.get(0).getChildren();
                for(Element e2 : elements_2) {
                    String e2name=e2.getName();

                    if(e2name.equals("a_script")) {
                        a_script=e2.getValue();
                    }else if(e2name.equals("b_script")) {
                        b_script=e2.getValue();
                    }
                }

                userscript.link_select_script=new LinkSelectScript(a_script, b_script);
            }else {

            }
        }

        // radio_popup_all: 单选人对话框, 不指定顶级orgcode
        if(uiface.equals(Constants.UIFACE_RADIO_POPUP_ALL)) {
            List<Element> nodelist=e.getChildren(Constants.UIFACE_RADIO_POPUP_ALL + "_script");
            if(nodelist.size() == 1) {
                // 正确

                String defaultvalue=null;

                List<Element> elements_2 =nodelist.get(0).getChildren();
                for(Element e2 : elements_2) {
                    String e2name=e2.getName();

                    if(e2name.equals("defaultvalue")) {
                        defaultvalue=e2.getValue();
                    }
                }

                userscript.radio_popup_all=new RadioPopupAll(defaultvalue);

            }else {

            }
        }

        // radio_popup_value: 单选人对话框, 指定具体orgcode
        if(uiface.equals(Constants.UIFACE_RADIO_POPUP_VALUE)) {
            List<Element> nodelist=e.getChildren(Constants.UIFACE_RADIO_POPUP_VALUE + "_script");
            if(nodelist.size() == 1) {
                // 正确

                String orgcode=null;
                String defaultvalue=null;

                List<Element> elements_2 =nodelist.get(0).getChildren();
                for(Element e2 : elements_2) {
                    String e2name=e2.getName();

                    if(e2name.equals("orgcode")) {
                        orgcode=e2.getValue();
                    }else if(e2name.equals("defaultvalue")) {
                        defaultvalue=e2.getValue();
                    }
                }

                userscript.radio_popup_value=new RadioPopupValue(orgcode, defaultvalue);

            }else {

            }
        }

        // choose_popup_all: 多选人对话框，不指定顶级orgcode
        if(uiface.equals(Constants.UIFACE_CHOOSE_POPUP_ALL)) {
            List<Element> nodelist=e.getChildren(Constants.UIFACE_CHOOSE_POPUP_ALL + "_script");
            if(nodelist.size() == 1) {
                // 正确

                String defaultvalue=null;

                List<Element> elements_2 =nodelist.get(0).getChildren();
                for(Element e2 : elements_2) {
                    String e2name=e2.getName();

                    if(e2name.equals("defaultvalue")) {
                        defaultvalue=e2.getValue();
                    }
                }

                userscript.choose_popup_all=new ChoosePopupAll(defaultvalue);
            }else {

            }
        }

        // choose_popup_value：多选人对话框，指定具体orgcode
        if(uiface.equals(Constants.UIFACE_CHOOSE_POPUP_VALUE)) {
            List<Element> nodelist=e.getChildren(Constants.UIFACE_CHOOSE_POPUP_VALUE + "_script");
            if(nodelist.size() == 1) {
                // 正确

                String orgcode=null;
                String defaultvalue=null;

                List<Element> elements_2 =nodelist.get(0).getChildren();
                for(Element e2 : elements_2) {
                    String e2name=e2.getName();

                    if(e2name.equals("orgcode")) {
                        orgcode=e2.getValue();
                    }else if(e2name.equals("defaultvalue")) {
                        defaultvalue=e2.getValue();
                    }
                }

                userscript.choose_popup_value=new ChoosePopupValue(orgcode, defaultvalue);
            }else {

            }
        }

        return userscript;
    }

    public ConditionScript parse_condition_script(Element e) {
        // 迁移条件生效规则名称、描述
        String name=null;
        // 类型
        String type=null;
        //处理人脚本
        String script=null;

        List<Element> elements_1 = e.getChildren();
        if(elements_1.size() == 0)
            return null;

        for(Element e1 : elements_1) {

            String e1name=e1.getName();

            if(e1name.equals("name")) {
                name=e1.getValue().trim();
            }else if(e1name.equals("type")) {
                type=e1.getValue().trim();
                if(type.length() == 0)
                    type=null;
            }else if(e1name.equals("script")) {
                script=e1.getValue().trim();
                if(script.length() == 0)
                    script=null;
            }
        }

        //判断type是否正确
        if(type != null) {
            if(type.equals("sql") || type.equals("java")) {
                // 正确
            }else {

            }
        }

        return new ConditionScript(name, type, script);
    }

    public Hashtable<String, Transition> parse_transitions(Element e) {
        Hashtable<String, Transition> transitions=new Hashtable<String, Transition>();

        List<Element> elements_1 = e.getChildren();
        for(Element e1 : elements_1) {
            List<Element> elements_2 = e1.getChildren();

            // 状态迁移英文名称
            String name=null;
            // 状态迁移中文名
            String alias=null;
            // 描述
            String description=null;
            // 源状态英文名
            String from_state=null;
            // 目标状态英文名
            String to_state=null;
            // 先决条件
            Vector<String> pre_trigger=new Vector<String>();
            // 后续条件
            Vector<String> post_trigger=new Vector<String>();
            // 排序序号
            int sort_order=0;
            // 处理人脚本
            UserScript user_script=null;
            // 迁移条件生效规则
            ConditionScript condition_script=null;
            // 一票否决: true/false， 只有fromstate是会签节点才有效
            boolean onevote=false;
            // 默认处理意见
            String default_opinion=null;
            // 状态迁移显示对话框定义
            Hashtable<String, OAttribute> opt_attributes=new Hashtable<String, OAttribute>();

            for(Element e2 : elements_2) {
                String e2name=e2.getName();

                if(e2name.equals("name")) {
                    name=e2.getValue();
                }else if(e2name.equals("alias")) {
                    alias=e2.getValue();
                }else if(e2name.equals("description")) {
                    description=e2.getValue();
                }else if(e2name.equals("from_state")) {
                    from_state=e2.getValue();
                }else if(e2name.equals("to_state")) {
                    to_state=e2.getValue();
                }else if(e2name.equals("pre_trigger")) {
                    for(String clsname : e2.getValue().split(";")) {
                        pre_trigger.add(clsname);
                    }
                }else if(e2name.equals("post_trigger")) {
                    for(String clsname : e2.getValue().split(";")) {
                        post_trigger.add(clsname);
                    }
                }else if(e2name.equals("sort_order")) {
                    sort_order=Integer.parseInt(e2.getValue());
                }else if(e2name.equals("user_script")) {
                    user_script=parse_user_script(e2);
                }else if(e2name.equals("condition_script")) {
                    condition_script=parse_condition_script(e2);
                }else if(e2name.equals("onevote")) {
                    onevote=e2.getValue().equals("true");
                }else if(e2name.equals("default_opinion")) {
                    default_opinion=e2.getValue();
                }else if(e2name.equals("opt_attributes")) {
                    opt_attributes=parse_opt_attributes(e2);
                }
            }

            Transition transition=new Transition(name, alias, description, from_state, to_state, sort_order, user_script, condition_script, onevote, default_opinion, pre_trigger, post_trigger, opt_attributes);
            transitions.put(name, transition);
        }

        return transitions;
    }


    /**
     * 预览代码
     *
     * @param wfid 流程id
     * @return 预览数据列表
     */
    @Override
    public Map<String, String> previewCode(String wfid)
    {
        Map<String, String> dataMap = new LinkedHashMap<>();
        // 查询表信息
        TbUpeModelver tbUpeModelver = selectTbUpeModelverByWfid(wfid);
        String wfcontent = tbUpeModelver.getWfcontent();
        dataMap.put("default.xml.vm", wfcontent);
        return dataMap;
    }
}
